package com.xnyzc.lhy.order.common.pay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.xnyzc.lhy.common.constant.PayConstant;
import com.xnyzc.lhy.order.service.common.pay.IOaPaymentService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

/**
 * 支付宝支付回调通知
 *
 * @Author: 刘举
 * @Date: 2018/12/14 16:53
 */
@Api(description = "支付宝支付回调通知")
@Slf4j
@RestController
@RequestMapping("/oa/aliPay")
public class AliPayNotify {


    @Value("${global.ali.pay.payPublicKey}")
    private String aliPublicKey;

    private String signType = "RSA2";

    private String charset = "utf-8";

    @Autowired
    private IOaPaymentService iOaPaymentService;

    /**
     * aliPay支付回调
     *
     * @param request
     * @param response
     */
    @PostMapping(value = "/aliNotify")
    public void aliNotify(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter printWriter = null;
        try {
            printWriter = response.getWriter();
        } catch (IOException e) {
            log.error("支付宝回调请求失败！");
            // 通知支付宝结果
            printWriter.print("fail");
        }

        Map<String, String> params = new HashMap<String, String>(16);
        Map<String, String[]> requestParams = request.getParameterMap();
        if (requestParams.size() == 0) {
            log.error("支付宝回调获取请求参数失败！");
            printWriter.print("fail");
        }

        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            /** valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); **/
            params.put(name, valueStr);
        }

        // 获取支付宝的通知返回参数
        // 商户订单号
        String orderNo = request.getParameter("out_trade_no");
        // 支付宝交易凭证号
        String tradeNo = request.getParameter("trade_no");
        // 交易状态
        String tradeStatus = request.getParameter("trade_status");
        // 订单金额
        String totalAmount = request.getParameter("total_amount");
        // 交易付款时间
        String gmtPayment = request.getParameter("gmt_payment");
        // 回传参数
        String passBackParams = request.getParameter("passback_params");
        // 效验数据
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, aliPublicKey, charset, signType);
        } catch (AlipayApiException e) {
            log.error("支付宝回调数据效验异常，订单号：{}", orderNo);
            printWriter.print("fail");
        }

        // 验证失败
        if (!signVerified) {
            log.error("支付宝回调数据效验失败，订单号：{}", orderNo);
            printWriter.print("fail");
        }

        // 交易状态 0:交易关闭 1：交易成功
        Integer payStatus = -1;
        if (Objects.equals(tradeStatus, PayConstant.TRADE_CLOSED)) {
            payStatus = 0;
        } else if (Objects.equals(tradeStatus, PayConstant.TRADE_SUCCESS)) {
            payStatus = 1;
        }

        // 支付成功
        if (Objects.equals(tradeStatus, PayConstant.TRADE_SUCCESS) || Objects.equals(tradeStatus, PayConstant.TRADE_CLOSED)) {
            log.info("订单号：{}", orderNo);
            log.info("支付宝交易凭证号:{}", tradeNo);
            log.info("交易状态:{}", tradeStatus);
            log.info("订单金额:{}", totalAmount);
            log.info("交易付款时间:{}", gmtPayment);
            log.info("回传参数:{}", passBackParams);

            // 解析回传参数
            JSONObject jsonObject = null;
            try {
                String passBackStr = URLDecoder.decode(passBackParams, charset);
                jsonObject = JSONObject.parseObject(passBackStr);
            } catch (UnsupportedEncodingException e) {
                log.error("支付宝支付回传参数解析失败，订单号：{},回传内容：{}", orderNo, passBackParams);
            }
            // 进行业务逻辑处理
            iOaPaymentService.processAliPayNotify(payStatus, orderNo, tradeNo, totalAmount, gmtPayment, jsonObject,0);

        }

        // 通知支付宝回调成功
        printWriter.print("success");
    }
}
